﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Delegates_and_Events
{
    class Program
    {
        

        static void Main(string[] args)
        {
            Publisher pub = new Publisher();
            Subscriber1 sub1 = new Subscriber1();
            Subscriber2 sub2 = new Subscriber2();
            Subscriber3 sub3 = new Subscriber3();

            pub.myEvent += new MyEventHandler(sub1.OnEvent);
            pub.myEvent += new MyEventHandler(sub2.OnEvent);
            pub.myEvent += new MyEventHandler(sub3.OnEvent);

            pub.DoSomething();
            Console.ReadLine();
        }
    }

    public delegate void MyEventHandler(object subject, EventArgs e);

    public class Publisher
    {
        public event MyEventHandler myEvent;
        public void DoSomething()
        {
            Console.WriteLine("DoSomething invoked!");

            if (myEvent != null)
            {
                Delegate[] delArray = myEvent.GetInvocationList();
                foreach (Delegate del in delArray)
                {
                    MyEventHandler method = (MyEventHandler)del;
                    method.BeginInvoke(null, EventArgs.Empty, null, null);
                }
            }
        }
    }

    public class Subscriber1
    {
        public void OnEvent(object sender, EventArgs e)
        {
            Thread.Sleep(TimeSpan.FromSeconds(3));      // 模拟耗时三秒才能完成方法
            Console.WriteLine("Waited for 3 seconds, subscriber1 invoked!");
        }
    }

    public class Subscriber2
    {
        public void OnEvent(object sender, EventArgs e)
        {
            throw new Exception("Subsciber2 Failed");   // 即使抛出异常也不会影响到客户端
            //Console.WriteLine("Subscriber2 immediately Invoked!");
        }
    }

    public class Subscriber3
    {
        public void OnEvent(object sender, EventArgs e)
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));  // 模拟耗时两秒才能完成方法
            Console.WriteLine("Waited for 2 seconds, subscriber3 invoked!");
        }
    }
}
